package us.versus.them.glassifried;

import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.InterpolationMethod;
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.SpreadMethod;
import flash.display.Sprite;

import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;

import flash.geom.Matrix;

import flash.text.TextField;
import flash.text.StyleSheet;

/**
 *
 * Thx 2 http://technomono.com/blog/mac-button/
 *
 *
 */
class Glassing {

	public static var DROP_FILTER =  [ new flash.filters.DropShadowFilter() ];
	public static var WHITE_FILTER = [ new flash.filters.DropShadowFilter(0,0,0xFFFFFF,1,5,5) ];
	public static var GLOW_FILTER =  [ new flash.filters.GlowFilter() ];

	public static var DEFAULT_STYLESHEET = _default_stylesheet();

	private function new() {
	}

	public static function toRGB( r,g,b ) {
		return Math.floor( r ) << 16 | Math.floor( g ) << 8 | Math.floor( b );
	}

	public static function glassyText( r,g,b, tag, text, ?styleSheet ) {
		var new_game_text = Glassing.text( tag, '', text, 0, 0, styleSheet );
		return glassIt( r,g,b, new_game_text );
	}

	public static function glassIt( r,g,b, guts:DisplayObject ) {
		return glass_it_up( r,g,b, -1, -1, guts );
	}

	public static function makeGlass( r,g,b, w,h ) {
		return return glass_it_up( r,g,b, w, h );
	}

	// specify w,h or guts...
	public static function glass_it_up( r,g,b, w, h, ?guts:DisplayObject ) {
		if ( null != guts && w < 0 ) {
			w = f( 1.2 * guts.width );
			h = f( 1.4 * guts.height );

			guts.x = ( w - guts.width ) / 2;
			guts.y = ( h - guts.height ) / 2;
		}

		var up = baseGradient( r,g,b, w,h );

		if ( null != guts ) {
			guts.filters = WHITE_FILTER;
			up.addChild( guts );
		}

		return shine( up, w, h );
	}

	public static function shine( target:Sprite, w, h ) : Sprite {
		var shine = new Sprite();

		//trace( target.width + '/' + w + ' and ' + target.height + '/' + h );

		beginShineGradient( shine.graphics, w, h );
		shine.graphics.drawRoundRectComplex( 
			  6, 2
			, w - 6 * 2, h / 2
			, h, h, 0, 0
		);
		shine.graphics.endFill();
		target.addChild( shine );

		return target;
	} 

	public static function beginShineGradient( graphics, w, h ) {
		var matrix:Matrix = new Matrix();
		matrix.createGradientBox( w, h/2, Math.PI / 2 );

		graphics.beginGradientFill( 
			GradientType.LINEAR
			, [0xFFFFFF, 0xFFFFFF ] // colors
			, [0.9, 0.3]            // alphas
			, [100, 255]              // ratios
			, matrix
			, SpreadMethod.PAD
			, InterpolationMethod.LINEAR_RGB
			, 0
		);
	}

	public static function baseGradient( r,g,b, w,h ) {
		var up = new Sprite();

		beginBaseGradient( up.graphics, r,g,b, w,h );
		up.graphics.drawRoundRect( 
			0, 0
			, w, h
			, h, h 
		);
		up.graphics.endFill();

		return up;
	}

	public static function beginBaseGradient( graphics, r,g,b, w,h ) {
		var brightest = r;
		if ( g > brightest ) brightest = g;
		if ( b > brightest ) brightest = b;

		var darkest = r;
		if ( g < darkest ) darkest= g;
		if ( b < darkest ) darkest= b;

		var dfactor = darkest / 255;
		var bfactor = 255 / brightest;

		if ( dfactor < 1 ) dfactor = 1;

		var rl = r * dfactor;
		var gl = g * dfactor;
		var bl = b * dfactor;

		var rd = r * bfactor;
		var gd = g * bfactor;
		var bd = b * bfactor;

		var matrix:Matrix = new Matrix();
		matrix.createGradientBox( w, h, Math.PI * 7 / 16  );

		graphics.beginGradientFill( 
			GradientType.LINEAR
			, [ 
					 Glassing.toRGB( r, g, b )
					, Glassing.toRGB( rl, gl, bl )
					, Glassing.toRGB( rd, gd, bd ) 
			]
			//, [0x133b83, 0x4a88d5, 0x9bdefb ] // colors
			, [1, 1, 1]                       // alphas
			, [0, 120, 255]                   // ratios
			, matrix
			, SpreadMethod.PAD
			, InterpolationMethod.LINEAR_RGB
			, 0
		);
	}

	public static function text( tag, klass, text, x, y, ?styleSheet ) {
		var html = '<' + tag + ' class="' + klass + '">' + text + '</' + tag + '>';
		//var html = '<' + tag + '>' + text + '</' + tag + '>';

		var textField = Glassing.makeText( html, x, y, styleSheet );
		textField.filters = DROP_FILTER;

		return textField;
	}

	public static function makeText( html, x, y, ?styleSheet ) {
		if ( null == styleSheet ) styleSheet = DEFAULT_STYLESHEET;

		var textField = new TextField();
		textField.autoSize = flash.text.TextFieldAutoSize.LEFT;
		textField.x = x;
		textField.y = y;
		textField.styleSheet = styleSheet;
		textField.htmlText = html;
		textField.alwaysShowSelection = false;
		textField.selectable = false;
		textField.wordWrap = false;
		return textField;
	}

	public static function displayObjectToBitMapData( displayObject:DisplayObject ) {
		var bitmapData = new BitmapData( 
			Math.floor( displayObject.width  )
			, Math.floor( displayObject.height )
			, true
			, 0xFF0000
		);
		bitmapData.draw( displayObject );
		return bitmapData;
	}

	public static function f( n ) {
		return Math.floor( n );
	}

	private static function _default_stylesheet() {
		var styleSheet = new StyleSheet();
		styleSheet.parseCSS( ''
			+ 'h3 {'
			+ '    font-family: Arial, Helvetica, sans-serif;'
			+ '    font-size: 20px;'
			+ '    font-weight: 400;'
			+ '}'
			+ 'h4 {'
			+ '    font-family: Arial, Helvetica, sans-serif;'
			+ '    font-size: 24px;'
			+ '    font-weight: 600;'
			+ '}'
		);
		return styleSheet;
	}
}
